/*
 * Unidata Platform
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 *
 * Commercial License
 * This version of Unidata Platform is licensed commercially and is the appropriate option for the vast majority of use cases.
 *
 * Please see the Unidata Licensing page at: https://unidata-platform.com/license/
 * For clarification or additional options, please contact: info@unidata-platform.com
 * -------
 * Disclaimer:
 * -------
 * THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT ANY WARRANTIES, CONDITIONS AND
 * REPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
 * IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,
 * FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE AND
 * THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.
 */
package org.unidata.mdm.dq.core.module;


import javax.annotation.Nullable;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.unidata.mdm.dq.core.configuration.DataQualityCoreConfiguration;
import org.unidata.mdm.dq.core.configuration.DataQualityCoreConfigurationConstants;
import org.unidata.mdm.dq.core.migration.DataQualityCoreMigrations;
import org.unidata.mdm.system.context.DatabaseMigrationContext;
import org.unidata.mdm.system.service.DatabaseMigrationService;
import org.unidata.mdm.system.service.PlatformConfiguration;
import org.unidata.mdm.system.type.module.AbstractModule;
import org.unidata.mdm.system.type.pipeline.Segment;
import org.unidata.mdm.system.util.DataSourceUtils;

/**
 * @author Alexander Malyshev
 */
public class DataQualityModule extends AbstractModule {

    private static final Logger LOGGER = LoggerFactory.getLogger(DataQualityModule.class);
    public static final String MODULE_ID = "org.unidata.mdm.dq.core";

    @Autowired
    @Qualifier("dataQualityDataSource")
    private DataSource dataQualityDataSource;

    @Autowired
    private DatabaseMigrationService migrationService;

    @Autowired
    private PlatformConfiguration platformConfiguration;

    @Autowired
    private DataQualityCoreConfiguration dqCoreConfiguration;

    private boolean install;

    @Override
    public String getId() {
        return MODULE_ID;
    }

    @Override
    public String getVersion() {
        return "6.0";
    }

    @Override
    public String getName() {
        return "Data Quality";
    }

    @Override
    public String getDescription() {
        return "Data Quality module";
    }

    @Nullable
    @Override
    public String getTag() {
        return null;
    }

    @Override
    public void install() {
        LOGGER.info("Install");
        DataQualityCoreMigrations.init();
        migrate();
        install = true;
    }

    @Override
    public void uninstall() {
        LOGGER.info("Uninstall");
        migrationService.migrate(DatabaseMigrationContext.builder()
                .schemaName(DataQualityCoreConfigurationConstants.DQ_CORE_SCHEMA_NAME)
                .logName(DataQualityCoreConfigurationConstants.DQ_CORE_LOG_NAME)
                .dataSource(dataQualityDataSource)
                .migrations(DataQualityCoreMigrations.uninstall())
                .build());
    }

    @Override
    public void start() {

        LOGGER.info("Start");

        if (platformConfiguration.isDeveloperMode() && !install) {
            DataQualityCoreMigrations.init();
            migrate();
        }

        addSegments(dqCoreConfiguration.getBeansOfType(Segment.class).values());
    }

    @Override
    public void stop() {
        LOGGER.info("Stop");
        DataSourceUtils.shutdown(dataQualityDataSource);
    }

    private void migrate() {
        migrationService.migrate(DatabaseMigrationContext.builder()
                .schemaName(DataQualityCoreConfigurationConstants.DQ_CORE_SCHEMA_NAME)
                .logName(DataQualityCoreConfigurationConstants.DQ_CORE_LOG_NAME)
                .dataSource(dataQualityDataSource)
                .migrations(DataQualityCoreMigrations.install())
                .build());
    }
}
